package com.zjlanyun.erp.view;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.AndroidVersions;
import com.fntech.m10a.gpio.M10A_GPIO;
import com.zjlanyun.erp.Common;
import com.zjlanyun.erp.Data;
import com.zjlanyun.erp.MainApplication;
import com.zjlanyun.erp.R;
import com.zjlanyun.erp.config.AppConfig;
import com.zjlanyun.erp.nohttp.CallServer;
import com.zjlanyun.erp.rfid.m10.u8.reader.CMD;
import com.zjlanyun.erp.rfid.m10.u8.reader.ERROR;
import com.zjlanyun.erp.rfid.m10.u8.reader.model.InventoryBuffer;
import com.zjlanyun.erp.rfid.m10.u8.reader.model.OperateTagBuffer;
import com.zjlanyun.erp.rfid.m10.u8.reader.model.ReaderSetting;
import com.zjlanyun.erp.rfid.m10.u8.reader.server.ReaderBase;
import com.zjlanyun.erp.rfid.m10.u8.reader.server.ReaderHelper;
import com.zjlanyun.erp.rfid.m10.u8.utils.M10_GPIO;
import com.zjlanyun.erp.rfid.m10.u8.utils.StringTool;
import com.zjlanyun.erp.utils.StatusBarUtil;
import com.zjlanyun.erp.utils.Toastor;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import android_serialport_api.SerialPort;
import butterknife.Bind;
import butterknife.ButterKnife;

public class BaseRFIDActivity extends Activity {

    @Bind(R.id.title) public TextView title;
    @Bind(R.id.ll_back) public LinearLayout ll_back;
    @Bind(R.id.ll_status_bar) LinearLayout ll_status_bar;

    private int statusBarLightMode = 0;
    public Context mContext = this;

    //RFID主体参数
    private static String TAG = "RFIDActivity";
    private SerialPort mSerialPort = null;
    public ReaderHelper mReaderHelper;
    public ReaderBase mReader;
    public static ReaderSetting m_curReaderSetting;
    public static InventoryBuffer m_curInventoryBuffer = null;
    private static OperateTagBuffer m_curOperateTagBuffer;
    public LocalBroadcastManager lbm;
    public List<InventoryBuffer.InventoryTagMap> data;
    public String successMsg = "";
    public String failMsg = "";

    public String className = "";

    //RFID扩展
    public int scanNumber = 0; //0不限，达到该数量则停止盘询

    public static enum AccessAreaType {
        password,
        epc,
        tid,
        user
    }

    public static enum ActionType {
        read,
        write
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //设置状态栏颜色
        statusBarLightMode = StatusBarUtil.StatusBarLightMode(this);
        if (statusBarLightMode > 0) {
            StatusBarUtil.transparencyBar(this);
        }
    }

    @Override
    protected void onResume() {
        if (mReader != null) {
            if (!mReader.IsAlive())
                mReader.StartWait();
        }
        super.onResume();
    }

    /**
     * 基础初始化
     */
    public void initBaseView() {
        ButterKnife.bind(this);

        //显示布局文件中的状态栏
        if (statusBarLightMode > 0) {
            ll_status_bar.setVisibility(View.VISIBLE);
        }

        //后退
        ll_back.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });

        if (Build.MODEL.equals(Data.RFID_DEVICE)) {
            initRFID();

            //初始化本页功率
            int level = 1;
            StackTraceElement[] stacks = new Throwable().getStackTrace();
            className = stacks[level].getClassName();
            byte btOutputPower = (byte) AppConfig.getInstance().getInt("RFID" + className, 0);
            if (btOutputPower > 0) {
//                m_curReaderSetting.btAryOutputPower = new byte[]{btOutputPower};
                int ret = mReader.setOutputPower(m_curReaderSetting.btReadId, btOutputPower);
                if (ret == 0) {
                    m_curReaderSetting.btAryOutputPower = new byte[]{btOutputPower};
                }
            }
        }
    }

    /**
     * 初始化RFID模块
     */
    private void initRFID() {
        data = new ArrayList<>();
//        PrepareWork();

        try {
            mReaderHelper = ReaderHelper.getDefaultHelper();
//            mReaderHelper.setReader(mSerialPort.getInputStream(), mSerialPort.getOutputStream());
            mReader = mReaderHelper.getReader();
        } catch (Exception e) {
            e.printStackTrace();
        }
        m_curReaderSetting = mReaderHelper.getCurReaderSetting();
        m_curInventoryBuffer = mReaderHelper.getCurInventoryBuffer();
        m_curOperateTagBuffer = mReaderHelper.getCurOperateTagBuffer();

        lbm = LocalBroadcastManager.getInstance(this);
        IntentFilter itent = new IntentFilter();
        itent.addAction(ReaderHelper.BROADCAST_REFRESH_FAST_SWITCH);
        itent.addAction(ReaderHelper.BROADCAST_REFRESH_INVENTORY);
        itent.addAction(ReaderHelper.BROADCAST_REFRESH_INVENTORY_REAL);
        itent.addAction(ReaderHelper.BROADCAST_REFRESH_ISO18000_6B);
        itent.addAction(ReaderHelper.BROADCAST_REFRESH_OPERATE_TAG);
        itent.addAction(ReaderHelper.BROADCAST_REFRESH_READER_SETTING);
        itent.addAction(ReaderHelper.BROADCAST_WRITE_LOG);
        itent.addAction(ReaderHelper.BROADCAST_WRITE_DATA);
        lbm.registerReceiver(mRecv, itent);
    }

    /**
     * 模块上电，打开串口
     */
    private void PrepareWork() {
        if (android.os.Build.VERSION.RELEASE.equals(AndroidVersions.V_4_0_3)) {
            M10_GPIO.R1000_PowerOn(); //模块上电
            try {
                mSerialPort = new SerialPort(new File("dev/ttySAC2"), 115200, 0);
            } catch (SecurityException e1) {
                e1.printStackTrace();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        } else if (android.os.Build.VERSION.RELEASE.equals(AndroidVersions.V_5_1_1)) {
            M10A_GPIO.PowerOn(); //模块上电
            try {
                M10A_GPIO._uhf_SwitchSerialPort();
                mSerialPort = new SerialPort(new File("/dev/ttyHSL0"), 115200, 0);
            } catch (SecurityException e1) {
                e1.printStackTrace();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        } else {
            Toastor.getInstance().showToast("程序版本有误，请联系技术支持人员！");
        }
    }

    /**
     * 模块下电，关闭串口
     */
    private void EndWork() {
        mSerialPort.close();
        if (android.os.Build.VERSION.RELEASE.equals(AndroidVersions.V_4_0_3)) {
            M10_GPIO.R1000_PowerOFF();
        } else if (android.os.Build.VERSION.RELEASE.equals(AndroidVersions.V_5_1_1)) {
            M10A_GPIO.PowerOff();
        }
    }

    public int getSessionState() {
        SharedPreferences spf = this.getSharedPreferences("setting", Activity.MODE_PRIVATE);
        int state = spf.getInt("_session", 0);
        return state;
    }

    public int getFlagState() {
        SharedPreferences spf = this.getSharedPreferences("setting", Activity.MODE_PRIVATE);
        int state = spf.getInt("_flag", 0);
        return state;
    }

    public Handler mHandler = new Handler();
    public Runnable mRefreshRunnable = new Runnable() {
        public void run() {
            refreshList();
            refreshText();
            mHandler.postDelayed(this, 2000);
        }
    };

    public Handler mLoopHandler = new Handler();
    public Runnable mLoopRunnable = new Runnable() {
        public void run() {
            byte btWorkAntenna = m_curInventoryBuffer.lAntenna
                    .get(m_curInventoryBuffer.nIndexAntenna);
            if (btWorkAntenna < 0)
                btWorkAntenna = 0;

            mReader.setWorkAntenna(m_curReaderSetting.btReadId, btWorkAntenna);
            mLoopHandler.postDelayed(this, 2000);
        }
    };


    public void refreshList() {
        data.clear();
        data.addAll(m_curInventoryBuffer.lsTagList);
    }

    public void refreshText() {
        if (scanNumber > 0 && m_curInventoryBuffer.lsTagList.size() >= scanNumber) {
            stopScan();
        }
    }

    private final BroadcastReceiver mRecv = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(ReaderHelper.BROADCAST_REFRESH_FAST_SWITCH)) {
                Log.i(TAG, "ReaderHelper.BROADCAST_REFRESH_FAST_SWITCH");
            } else if (intent.getAction().equals(ReaderHelper.BROADCAST_REFRESH_INVENTORY)) {
                Log.i(TAG, "ReaderHelper.BROADCAST_REFRESH_INVENTORY");
            } else if (intent.getAction().equals(ReaderHelper.BROADCAST_REFRESH_INVENTORY_REAL)) {
                Log.i(TAG, "ReaderHelper.BROADCAST_REFRESH_INVENTORY_REAL");

                byte btCmd = intent.getByteExtra("cmd", (byte) 0x00);

                switch (btCmd) {
                    case CMD.REAL_TIME_INVENTORY:
                    case CMD.CUSTOMIZED_SESSION_TARGET_INVENTORY:
                        refreshText();
                        break;
                    case ReaderHelper.INVENTORY_ERR:
                    case ReaderHelper.INVENTORY_ERR_END:
                    case ReaderHelper.INVENTORY_END:
                        if (mReaderHelper.getInventoryFlag()) {
                            //防止盘询失败
                        } else {
                            mLoopHandler.removeCallbacks(mLoopRunnable);
                        }
                        refreshList();
                        break;
                }

            } else if (intent.getAction().equals(ReaderHelper.BROADCAST_REFRESH_ISO18000_6B)) {
                Log.i(TAG, "ReaderHelper.BROADCAST_REFRESH_ISO18000_6B");
            } else if (intent.getAction().equals(ReaderHelper.BROADCAST_REFRESH_OPERATE_TAG)) {
                Log.i(TAG, "ReaderHelper.BROADCAST_REFRESH_OPERATE_TAG");
                byte btCmd = intent.getByteExtra("cmd", (byte) 0x00);
                byte type = intent.getByteExtra("type", (byte) 0x00);
                String msg = intent.getStringExtra("msg");

                switch (btCmd) {
                    case CMD.GET_ACCESS_EPC_MATCH:
                        break;
                    case CMD.READ_TAG:
                        if (ERROR.FAIL == type) {
//                            returnData.setText("");
                        } else {
//                            returnData.setText(msg);
                        }
                        break;
                    case CMD.WRITE_TAG:
                        writeResult(type, msg);
                        break;
                    case CMD.LOCK_TAG:
                        break;
                    case CMD.KILL_TAG:
                        break;
                }
            } else if (intent.getAction().equals(ReaderHelper.BROADCAST_REFRESH_READER_SETTING)) {
                Log.i(TAG, "ReaderHelper.BROADCAST_REFRESH_READER_SETTING");
            } else if (intent.getAction().equals(ReaderHelper.BROADCAST_WRITE_LOG)) {
                Log.i(TAG, "ReaderHelper.BROADCAST_WRITE_LOG");
            } else if (intent.getAction().equals(ReaderHelper.BROADCAST_WRITE_DATA)) {
                Log.i(TAG, "ReaderHelper.BROADCAST_WRITE_DATA");
            }
        }
    };

    /**
     * 写卡结果操作
     *
     * @param type
     * @param msg
     */
    public void writeResult(byte type, String msg) {
        if (ERROR.SUCCESS == type && !successMsg.equals("")) {
            Toastor.getInstance().showShortToast(successMsg);
        } else if (ERROR.FAIL == type && !failMsg.equals("")) {
            Toastor.getInstance().showShortToast(failMsg);
        } else {
            Toastor.getInstance().showShortToast(msg);
        }
    }

    /**
     * 开始扫描
     */
    public void startScan() {
        m_curInventoryBuffer.clearInventoryPar();
        m_curInventoryBuffer.bLoopCustomizedSession = true;
        m_curInventoryBuffer.btSession = (byte) (getSessionState() & 0xFF);
        m_curInventoryBuffer.btTarget = (byte) (getFlagState() & 0xFF);
        m_curInventoryBuffer.lAntenna.add((byte) 0x01);
        m_curInventoryBuffer.bLoopInventoryReal = true;
        m_curInventoryBuffer.btRepeat = (byte) 1;
        m_curInventoryBuffer.clearInventoryRealResult();

        mReaderHelper.setInventoryFlag(true);
        mReaderHelper.clearInventoryTotal();

        byte btWorkAntenna = m_curInventoryBuffer.lAntenna.get(m_curInventoryBuffer.nIndexAntenna);
        if (btWorkAntenna < 0)
            btWorkAntenna = 0;

        mReader.setWorkAntenna(m_curReaderSetting.btReadId, btWorkAntenna);
        m_curReaderSetting.btWorkAntenna = btWorkAntenna;
        mHandler.removeCallbacks(mRefreshRunnable);
        mHandler.postDelayed(mRefreshRunnable, 500);
    }

    /**
     * 停止扫描
     */
    public void stopScan() {
        mReaderHelper.setInventoryFlag(false);
        m_curInventoryBuffer.bLoopInventory = false;
        m_curInventoryBuffer.bLoopInventoryReal = false;
        mLoopHandler.removeCallbacks(mLoopRunnable);
        mHandler.removeCallbacks(mRefreshRunnable);
    }

    /**
     * 设置操作的EPC号
     *
     * @param strEPC
     */
    public void setEPC(String strEPC) {
        byte[] btAryEpc = null;

        try {
            String[] result = StringTool.stringToStringArray(strEPC, 2);
            btAryEpc = StringTool.stringArrayToByteArray(result, result.length);
        } catch (Exception e) {
            Toastor.getInstance().showShortToast("EPC设置错误");
            return;
        }

        if (btAryEpc == null) {
            Toastor.getInstance().showShortToast("EPC设置错误");
            return;
        }

        mReader.setAccessEpcMatch(m_curReaderSetting.btReadId, (byte) (btAryEpc.length & 0xFF), btAryEpc);
    }

    /**
     * 读写卡
     *
     * @param actionType     read读，write写
     * @param accessAreaType 访问区域
     * @param startAddr      (WORD) 偏移，起始地址从0开始，默认0
     * @param password       (HEX) 访问密码，默认00 00 00 00
     * @param dataLen        (WORD) 长度，默认4
     * @param writeData      (HEX) 写入的数据
     */
    public void readOrWrite(ActionType actionType, AccessAreaType accessAreaType, String startAddr, String password, int dataLen, String writeData) {
        byte btMemBank = 0x00;
        byte btWordAdd = 0x00;
        byte btWordCnt = 0x00;
        byte[] btAryPassWord = null;
        if (accessAreaType == AccessAreaType.password) {
            btMemBank = 0x00;
        } else if (accessAreaType == AccessAreaType.epc) {
            btMemBank = 0x01;
        } else if (accessAreaType == AccessAreaType.tid) {
            btMemBank = 0x02;
        } else if (accessAreaType == AccessAreaType.user) {
            btMemBank = 0x03;
        }
        try {
            btWordAdd = (byte) Integer.parseInt(startAddr);
        } catch (Exception e) {
            Toastor.getInstance().showShortToast("起始地址格式错误");
            return;
        }
        try {
            String[] reslut = StringTool.stringToStringArray(password.toUpperCase(), 2);
            btAryPassWord = StringTool.stringArrayToByteArray(reslut, 4);
        } catch (Exception e) {
            Toastor.getInstance().showShortToast("访问密码错误");
            return;
        }
        if (actionType == ActionType.read) {
            try {
                btWordCnt = (byte) dataLen;
            } catch (Exception e) {
                Toastor.getInstance().showShortToast("长度错误");
                return;
            }

            if ((btWordCnt & 0xFF) <= 0) {
                Toastor.getInstance().showShortToast("长度错误");
                return;
            }

            m_curOperateTagBuffer.clearBuffer();
            mReader.readTag(m_curReaderSetting.btReadId, btMemBank, btWordAdd, btWordCnt, btAryPassWord);
        } else if (actionType == ActionType.write) {
            byte[] btAryData = null;
            String[] result = null;
            try {
                result = StringTool.stringToStringArray(writeData.toUpperCase(), 2);
                btAryData = StringTool.stringArrayToByteArray(result, result.length);
                btWordCnt = (byte) ((result.length / 2 + result.length % 2) & 0xFF);
            } catch (Exception e) {
                Toastor.getInstance().showShortToast("写入数据错误");
                return;
            }

            if (btAryData == null || btAryData.length <= 0) {
                Toastor.getInstance().showShortToast("写入数据错误");
                return;
            }

            if (btAryPassWord == null || btAryPassWord.length < 4) {
                Toastor.getInstance().showShortToast("访问密码错误");
                return;
            }
//            mDataLenEditText.setText(String.valueOf(btWordCnt & 0xFF));
            m_curOperateTagBuffer.clearBuffer();
            mReader.writeTag(m_curReaderSetting.btReadId, btAryPassWord, btMemBank, btWordAdd, btWordCnt, btAryData);
        }
    }

    @Override
    protected void onDestroy() {
        stopScan();
        CallServer.getRequestInstance().cancelBySign(mContext);
        super.onDestroy();
        ButterKnife.unbind(this);

        if (lbm != null)
            lbm.unregisterReceiver(mRecv);

        mLoopHandler.removeCallbacks(mLoopRunnable);
        mHandler.removeCallbacks(mRefreshRunnable);


//        if (Build.MODEL.equals(Data.RFID_DEVICE)) {
//            EndWork();
//        }
    }
}
